package com.asen.commons.core.base.service.impl;

import com.asen.commons.core.base.domain.BaseEntry;
import com.asen.commons.core.base.service.BaseEntryService;
import com.asen.commons.core.meta.dao.Condition;
import com.asen.commons.core.utils.EntityUtils;
import com.asen.commons.utils.IdUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 通用service抽象类
 *
 * @author Gary
 * @version 1.0
 * @date 2018-12-13
 */
public abstract class AbstractBaseEntryServiceImpl<T extends BaseEntry> extends AbstractSubBaseServiceImpl<T> implements BaseEntryService<T> {

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void addEntry(List<T> entryList, Long parentId) throws Exception {
        if (entryList == null || entryList.isEmpty() || parentId == null || parentId == 0L) {
            return;
        }

        int seqNum = 1;
        for (T entry : entryList) {
            if (Boolean.TRUE.equals(entry.getIsDeleted())) {
                continue;
            }
            entry.setParentId(parentId);
            entry.setSeqNum(seqNum++);
            add(entry);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateEntry(List<T> entryList, Long parentId) throws Exception {
        if (parentId == null || parentId == 0L) {
            return;
        }

        if (CollectionUtils.isEmpty(entryList)) {
            removeEntry(parentId);
            return;
        }

        int seqNum = 1;
        for (T entry : entryList) {
            entry.setParentId(parentId);
            if (EntityUtils.isEmpty(entry.getId())) {
                if (Boolean.TRUE.equals(entry.getIsDeleted())) {
                    continue;
                }
                entry.setSeqNum(seqNum++);
                add(entry);
            } else if (Boolean.TRUE.equals(entry.getIsDeleted())) {
                remove(entry);
            } else {
                entry.setSeqNum(seqNum++);
                update(entry);
            }
        }

        // 删除不在update列表的分录数据
        Condition condition = new Condition();
        condition.equal("parentId", parentId);
        condition.notIn("id", entryList.stream().map(BaseEntry::getId).collect(Collectors.toList()));
        List<T> dbList = getList(condition);
        for (T entry : dbList) {
            remove(entry);
        }
    }

    @Override
    public void removeEntry(Long parentId) throws Exception {
        Condition condition = new Condition();
        condition.equal("parentId", parentId);
        List<T> dbList = getList(condition);
        for (T entry : dbList) {
            remove(entry);
        }
    }

    @Override
    public List<T> getListByParentId(Long parentId) throws Exception {
        if (IdUtils.isEmpty(parentId)) {
            return null;
        }
        Condition condition = new Condition();
        condition.equal("parentId", parentId);
        condition.orderByAsc("seqNum");
        return getList(condition);
    }
}
